<?php
namespace app\common\model;

use think\Model;
use app\v2\model\Apply;
use think\Db;
use app\admin\logic\Pay;
use app\v2\model\Pay as V2Pay;
use app\admin\model\Repayment;
use fuiou\FuiouApi;
use app\v2\controller\Script;


/**
 * 商家打款类
 */
class Payment extends Model
{
    public function __construct()
    {
        parent::__construct();
        date_default_timezone_set('Asia/Shanghai');
    }

    
    /**
     * 商家付款 接口  
     * @author   yhq <934797303@qq.com>
     * @DateTime 2018-03-22T19:20:14+0800
     * @param    [type]       $param [打款订单信息]
     * @return   [type]              [description]
     */
    public function payment($param){
        $applyModel = new Apply;
        $phone = $applyModel->where('uid',$param['uid'])->value('phone');

        $data = [
            'orderno'  => $param['no_order'],   // 请求流水 数字串，当天必须唯一
            'bankno'   => $param['bankno'],     // 总行代码
            'cityno'   => '1000',               // 城市代码
            'branchnm' => '默认为空',            // 支行名称 可不填，如果填写，一定要填对，否则影响交易；但对公户、城商行、农商行、信用社必须填支行，且需正确的支行信息
            'amt'      => $param["total_money"] * 100,                // 金额 单位：分（单笔最少 3 元）
            'accntno'  => $param['card_no'],      // 用户银行账号
            'accntnm'  => $param['acct_name'],    // 用户账户名称
            'mobile'   => $phone,                 // 手机号  短信通知时使用  可不填
            'entseq'   => '默认为空',              // 企业流水号 填写后，系统体现在交易查询中 可不填
            'memo'     => '默认为空',              // 备注  填写后，系统体现在交易查询中 可不填
        ]; 

        // 参数过滤
        foreach ($data as $key => $value) {
            if(empty($value)){
                $this->error = '参数为空:'.$key;
                return false;
            }
        }
        $data['branchnm'] = $data['entseq'] = $data['memo'] = ''; //这几个参数保持空

        $FuiouApi = (new FuiouApi)->pay($data);
       
        $data['adminName'] = Db::name('admin_user')->where('id', $param['admin_uid'])->value('username'); // 打款操作员
        $data['order_number'] = $param['apply_id'];  //原始申请单号
        $data['fuiouRes'] = json_encode($FuiouApi, JSON_UNESCAPED_UNICODE); //富友返回结果

        // 打款信息
        $orderno      = $data['orderno'];
        $adminName    = $data['adminName'];
        $accntno      = substr($data['accntno'],0,3).'****'.substr($data['accntno'],-4);
        $accntnm      = $data['accntnm'];
        $order_number = $data['order_number'];
        $fuiouRes     = $data['fuiouRes'];
        $pay_money = $param["total_money"];
        
        $time = date('Y-m-d :H:i:s'); 
        $result = "[{$time}] 后台发起打款，打款单号:{$orderno} ，原始申请单号:{$order_number}，操作员:{$adminName}，金额：{$pay_money}，收款账户:{$accntno}，收款人：{$accntnm}，富友返回结果:{$fuiouRes}";
        @file_put_contents(LOGS_DIR_NAME."payment.log", $result."\n\n", FILE_APPEND);  //记录日志

        if($FuiouApi['ret'] != '000000'){
            // 处理富友的订单重复
            $paymentOrderModel = new paymentOrder; 
            $dataP['status']      = 3; //打款失败
            $dataP['result_pay']  = 'FAILURE';//支付结果，FAILURE：为支付失败
            $dataP['ret_msg']     = $FuiouApi['memo'];  // 交易结果描述 
            $dataP['reason']      = '富友失败，此订单作废';  // 详细描述
            $dataP['update_time'] = date('Y-m-d H:i:s');           
            $updateP = $paymentOrderModel->save($dataP, ['no_order'=>$param['no_order']]); 

            $this->error = $FuiouApi['memo'];
            return false;
        }

        // 放款处理中
        $dataA['is_loaning'] = 1; 
        $res = $applyModel->where('order_number', $param['apply_id'])->update($dataA); 

        return $FuiouApi['transStatusDesc'];
    }


    /**
     * 更新打款单信息
     * @author yhq <934797303@qq.com>
     * @date   2018-03-27
     * @param  [type]     $notifyResp [查询结果]
     * @return [type]                 [description]
     */
    public function updatePaymentInfo($notifyResp)
    {
        // 验签
        // $checkSignature = (new FuiouApi)->checkSignature($notifyResp);
        // if($notifyResp['mac'] && !$checkSignature){
        //     $this->error = '验签失败';
        //     return false;
        // }
        
        $no_order = $notifyResp['orderno']; // 商户订单号
        $paymentOrderModel = new paymentOrder; 
        $ApplyModel = new Apply(); 
        $pay_order_info = $paymentOrderModel->where(["no_order"=>$no_order])->find(); 
        if(!$pay_order_info) {
            $this->error = "未找到打款单号";
            return false;
        } 

        Db::startTrans();
        try {
            $time = time();

            if ($notifyResp['futporderno'] || $notifyResp['tpst']=='1') { // 退票处理
                $dataA['is_loaning'] = 0; //解除放款处理中
                $dataP['status']     = 3; //打款失败
                $dataP['result_pay'] = 'FAILURE';//支付结果，FAILURE：为支付失败

            } else {  //付款处理
                switch ($notifyResp['state']) {
                    case '0': //交易未发送
                        break;
                    case '1': //交易已发送且成功
                        if($pay_order_info['result_pay'] != 'SUCCESS'){
                            $appoint_time = date('Y-m-d H:i:s', $time + 24*3600*$pay_order_info['period']);
                            $dataA['appoint_time'] = $appoint_time;
                            $dataA['fk_time']      = date('Y-m-d H:i:s', $time);
                            $dataA['status']       = 3; //打款成功
                            $dataA['is_loaning']   = 0; //解除放款处理中

                            $dataP['status']      =  1; //打款成功
                            $dataP['money_order'] =  $notifyResp['amt']/100;// 交易金额 实收金额
                            $dataP['result_pay']  =  'SUCCESS';//支付结果，SUCCESS：为支付成功
                            $dataP['settle_date'] =  date('Y-m-d H:i:s');// 账务日期  回调时间
                            $dataP['appoint_time'] = $appoint_time;
                        }
                        break;
                    case '2': //交易已发送且失败
                        $dataA['is_loaning'] = 0; //解除放款处理中
                        $dataP['status']     = 3; //打款失败
                        $dataP['result_pay'] = 'FAILURE';//支付结果，FAILURE：为支付失败
                        break;
                    case '3': //（需要接口/平台查询确认最终结果） 交易发送中
                        break;
                    case '7': //配置二次查询，会有此状态） 交易超时
                        break;
                    default:
                       
                        break;
                }
            }

            $dataP['ret_code']    = $notifyResp['state'];   // 交易结果代码 
            $dataP['ret_msg']     = $notifyResp['result'];  // 交易结果描述 
            $dataP['reason']      = $notifyResp['reason'];  // 详细描述
            $dataP['update_time'] = date('Y-m-d H:i:s', $time);

            // 更新申请单
            $updateA = $ApplyModel->save($dataA, ['order_number'=>$pay_order_info['apply_id']]);
            // 更新打款单
            $updateP = $paymentOrderModel->save($dataP, ['no_order'=>$no_order]); 

            if($updateA && $updateP){
                Db::commit();
                return true;
            }else{
                Db::rollback();
                $this->error = "打款订单处理失败";
                return false;  
            }
            
        } catch (\Exception $e) {
            Db::rollback();
            $this->error = "打款订单处理异常";
            return false;  
        }

    }






    /**
     * 确认付款
     * @Author      火星车11号
     * @email       704184317@qq.com
     * @create_time 2017-10-13T09:33:07+0800
     * @param       
     * @return      
     */
    public function payment_confirm($param)
    {
        /**************************请求参数**************************/

        //商户付款流水号
        $no_order = $param["no_order"];

        // 确认码
        $confirm_code = $param["confirm_code"];

        //服务器异步通知地址
        $notify_url = $this->notify_url;

        //平台来源
        $platform = $this->platform;

        //版本号
        $api_version = '1.0';

        /************************************************************/
        $llpay_config = config('llpay');
        //构造要请求的参数数组，无需改动
        $parameter = array (
            "oid_partner" => trim($llpay_config['oid_partner']),
            "sign_type" => trim($llpay_config['sign_type']),
            "platform" => $platform,
            "api_version" => $api_version,
            "no_order" => $no_order,
            "confirm_code" => $confirm_code,
            "notify_url" => $notify_url,
        );
        //建立请求
        $llpaySubmit = new LLpaySubmit($llpay_config);
        //对参数排序加签名
        $sortPara = $llpaySubmit->buildRequestPara($parameter);
        //传json字符串
        $json = json_encode($sortPara);    
        $parameterRequest = array (
            "oid_partner" => trim($llpay_config['oid_partner']),
            "pay_load" => ll_encrypt($json,$llpay_config['LIANLIAN_PUBLICK_KEY']) //请求参数加密
        );
        $html_text = $llpaySubmit->buildConfiemRequestJSON($parameterRequest);

        $html_text_arr = $this->object_array(json_decode($html_text));
        # 判断是否有 sign 数据 没有则 打款失败
        if(!isset($html_text_arr["sign"])){
            $this->error = $html_text_arr["ret_msg"];
            return false;
        }
        //调用付款申请接口，同步返回0000，是指创建连连支付单成功，订单处于付款处理中状态，最终的付款状态由异步通知告知
        //出现1002，2005，4006，4007，4009，9999这6个返回码时或者没返回码，抛exception（或者对除了0000之后的code都查询一遍查询接口）调用付款结果查询接口，明确订单状态，不能私自设置订单为失败状态，以免造成这笔订单在连连付款成功了，
        //而商户设置为失败,用户重新发起付款请求,造成重复付款，商户资金损失

        //对连连响应报文内容需要用连连公钥验签

        # 调用验签方法
        $notice_res=$this->handle_notice($html_text);

        if(!$notice_res["res"]){
            $this->error = "验签失败";
            return false;
        }
        $paymentOrderModel = new paymentOrder;
        $order_info = $paymentOrderModel->where(["no_order"=>$notice_res["data"]["no_order"]])->find();          
        #验签成功 查看支付结果 最终结果以异步回调结果为准

        # 正在支付 等待回调结果
        $order_info->ret_code     =   isset($notice_res["data"]["ret_code"])?$notice_res["data"]["ret_code"]:"";
        $order_info->ret_msg      =   isset($notice_res["data"]["ret_msg"])?$notice_res["data"]["ret_msg"]:"";            
        $order_info->oid_paybill =   isset($notice_res["data"]["oid_paybill"])?$notice_res["data"]["oid_paybill"]:"";
        $order_info->confirm_code =   isset($notice_res["data"]["confirm_code"])?$notice_res["data"]["confirm_code"]:"";
        $order_info->save();
        if($notice_res["data"]["ret_code"]=="0000"){
            return true;
        } else {
            $this->error = $notice_res["data"]["ret_msg"].":".$notice_res["data"]["ret_code"];
            return false;
        }
    }
    /**
     * 查询订单状态
     * @Author      火星车11号
     * @email       704184317@qq.com
     * @create_time 2017-10-13T10:56:59+0800
     */
    public function queryPayment($param) 
    {
        /**************************请求参数**************************/

        //商户付款流水号
        $no_order = $param["no_order"];
        // $oid_paybill = $param["oid_paybill"];

        //平台来源
        $platform = $this->platform;

        //版本号
        $api_version = '1.0';

        /************************************************************/
        $llpay_config = config('llpay');
        //构造要请求的参数数组，无需改动
        $parameter = array (
            "oid_partner" => trim($llpay_config['oid_partner']),
            "sign_type" => trim($llpay_config['sign_type']),
            "api_version" => $api_version,
            "no_order" => $no_order,
        );  
        //建立请求
        $llpaySubmit = new LLpaySubmit($llpay_config);
        //对参数排序加签名
        $sortPara = $llpaySubmit->buildRequestPara($parameter);

        $html_text = $llpaySubmit->buildQueryPaymentRequestJSON($sortPara);

        $html_text_arr = $this->object_array(json_decode($html_text));

        # 判断是否有 sign 数据 没有则 打款失败
        if(!isset($html_text_arr["sign"])){
            $this->error = $html_text_arr["ret_msg"];
            return false;
        }
        # 调用验签方法
        $notice_res=$this->query_Notify($html_text);

        if(!$notice_res["res"]){
            $this->error = "验签失败";
            return false;
        } 
        $result_pay =  $notice_res["data"]['result_pay'];//支付结果，SUCCESS：为支付成功
        if($result_pay == "SUCCESS"){
            $no_order =    $notice_res["data"]['no_order'];//商户订单号
            $oid_paybill = $notice_res["data"]['oid_paybill'];//连连支付单号
            $money_order = $notice_res["data"]['money_order'];// 支付金额
            $result_pay =  $notice_res["data"]['result_pay'];//支付结果，SUCCESS：为支付成功
            $settle_date = $notice_res["data"]['settle_date'];// 支付金额 
            $ret_code = $notice_res["data"]['ret_code'];// 支付金额 
            $ret_msg = $notice_res["data"]['ret_msg'];// 支付金额 
            $paymentOrderModel = new paymentOrder; 
            $pay_order_info = $paymentOrderModel->where(["no_order"=>$no_order])->find(); 
            if(!$pay_order_info) {
                $this->error = "没有找到订单号";
                return false;
            }
            $pay_order_info->oid_paybill =  $oid_paybill;
            $pay_order_info->money_order =  $money_order;
            $pay_order_info->result_pay  =  $result_pay;
            $pay_order_info->settle_date =  $settle_date;
            $pay_order_info->ret_code    =  $ret_code;
            $pay_order_info->ret_msg     =  $ret_msg;
            $pay_order_info->status      =   1;               //打款成功
            $pay_order_info->save();        

            $ApplyModel = new Apply(); 
            $apply_info = $ApplyModel->where(["order_number"=>$pay_order_info->apply_id])->find();

            $uid = $apply_info->uid;

            $dateDay = Db::name('system_config')->where(['name'=>'LOAN_PERIOD'])->find();
            $appoint_time = date('Y-m-d H:i:s',strtotime('+'.$dateDay["value"].' day'));

            $apply_info->appoint_time = $appoint_time;
            $apply_info->fangkuan_time = date('Y-m-d H:i:s',time());
            $apply_info->status = 1;
            $apply_info->save();

            Db::name('user_info')->where('uid', $uid)->update(['apple_pwd' => null,'state' => 9,'fangkuan_time'=>date('Y-m-d H:i:s',time())]);                    
            return true;       
        }
        $this->error = "订单支付失败";
        return false;
       
    }
    /**
     * 异步验签 (供连连调用)
     * @Author      火星车11号
     * @email       704184317@qq.com
     * @create_time 2017-10-11T14:27:12+0800
     * @return      [type]                   [description]
     */
    public function async_notice()
    {
        $async_res = $this->handle_notice();
        file_put_contents(LOGS_DIR_NAME."paymeng_notic_log.txt", '支付时间:'.date('Y-m-d H:i:s',time()) . '-' . json_encode($async_res)."\n\n", FILE_APPEND);
# 数据格式
// {"res":true,
//  "data":{"oid_partner":"201709220000945943",
//         "dt_order":"20171012142353",
//         "no_order":"2017111355558",
//         "info_order":"苹果云贷",
//         "oid_paybill":"2017101264923751",
//         "money_order":"1.98",
//         "result_pay":"SUCCESS",
//         "settle_date":"20171012",
//         "sign_type":"RSA"}


        if ($async_res["res"]) { //验证成功
            //获取连连支付的通知返回参数，可参考技术文档中服务器异步通知参数列表
            $no_order = $async_res["data"]['no_order'];//商户订单号
            $oid_paybill = $async_res["data"]['oid_paybill'];//连连支付单号
            $money_order = $async_res["data"]['money_order'];// 支付金额
            $result_pay =$async_res["data"]['result_pay'];//支付结果，SUCCESS：为支付成功
            $settle_date = $async_res["data"]['settle_date'];// 支付金额

            $paymentOrderModel = new paymentOrder; 
            $pay_order_info = $paymentOrderModel->where(["no_order"=>$no_order])->find();
            if(!$pay_order_info) {
                die("{'ret_code':'9999','ret_msg':'没有找到订单'}");
            }
            if($pay_order_info->status==1) {
                die("{'ret_code':'0000','ret_msg':'交易成功'}");
            }   
            if($result_pay == "SUCCESS"){
                //  修改 申请表信息
                $ApplyModel = new Apply(); 
                $apply_info = $ApplyModel->where(["order_number"=>$pay_order_info->apply_id])->find();
                $appoint_time = date('Y-m-d H:i:s',strtotime('+'.(string)$apply_info['period'].' day'));
                $data['appoint_time'] = $appoint_time;
                $data['fk_time']      = date('Y-m-d H:i:s',time());
                $data['status']       = 3;
                $data['is_loaning']   = 0;
                $res1 = $ApplyModel->allowField(true)->save($data, ["order_number"=>$pay_order_info->apply_id]);
                
                //  修改支付订单表信息
                $pay_order_info->update_time = date('Y-m-d H:i:s');
                $pay_order_info->oid_paybill = $oid_paybill;
                $pay_order_info->money_order = $money_order;
                $pay_order_info->result_pay = $result_pay;
                $pay_order_info->settle_date = $settle_date;
                $pay_order_info->ret_code = "0000";
                $pay_order_info->ret_msg = "支付成功";
                $pay_order_info->status = 1;
                $res2 = $pay_order_info->save();
                
                //推送消息
                // $msg = new Message();
                // $uid = $apply_info->uid;
                // $bank_card = Db::name('user_info')->where('uid', $uid)->value('bank_card_number');
                // $fangkuan_aid = $apply_info->treasurer;
                // $content = '财务已放款，请注意查收尾数（'.substr($bank_card,-4).'）银行卡';
                // $add = $msg->messageWrite('FK', $content, $uid, $fangkuan_aid);

                //  输出回调结果
                if($res1 && $res2) {
                    # 回调成功
                    //加入计划
                    $result = $this->agreenoauthapply($pay_order_info->apply_id,$appoint_time);
                    die("{'ret_code':'0000','ret_msg':'交易成功'}"); //请不要修改或删除
                }else {
                    # 请求重新回调
                    die("{'ret_code':'9999','ret_msg':'写入失败'}"); //请不要修改或删除                    
                }
            }
        } else {
            //验证失败
            die("{'ret_code':'9999','ret_msg':'验签失败'}");
        }

    }
 



}
